
class Item extends egret.Sprite{

	public static L:Array<Array<number>> = [
		[1,0],
		[2,0],	
		[1,3]
	];	

	public static rL:Array<Array<number>> = [
		[0,3],
		[0,2],	
		[1,1]
	];	

	public static I:Array<Array<number>> = [
		[1],
		[2],	
		[1],	
		[1]
	];	

	public static T:Array<Array<number>> = [
		[1,2,1],	
		[0,3,0]
	];

	public static Z:Array<Array<number>> = [
		[1,2,0],	
		[0,3,1]
	];

	public static rZ:Array<Array<number>> = [
		[0,2,1],	
		[1,3,0]
	];

	public static O:Array<Array<number>> = [
		[1,2],	
		[1,3]
	];

	public static getCOG(d:Array<Array<number>>):egret.Point{
		let w:number = d[0].length;
		let h:number = d.length;
		return new egret.Point(Math.floor((w - 1)/2),Math.floor((h - 1)/2));
	}


	static type_list:Array<Array<Array<number>>>;
	static random():Array<Array<number>>{
		if(Item.type_list == null){
			Item.type_list = [Item.L,Item.rL,Item.I,Item.T,Item.Z,Item.rZ,Item.O];
		}
		return Item.type_list[Math.floor(Math.random() * Item.type_list.length)];
	}

	static pool:Array<Item> = [];
	public static create():Item{
		let result:Item;
		if(Item.pool.length > 0){
			result = Item.pool.shift();
			result.init();
		}else{
			result = new Item();
		}
		return result;
	}

	
	public gx:number = 0;
	public gy:number = 0;
	public data:Array<Array<number>>;
	public unitList:Array<Unit> = [];
	direction:number;

	public constructor(d:Array<Array<number>> = null,dir:number = -1){
		super();
		this.init(d,dir);
	}

	public init(d:Array<Array<number>> = null,dir:number = -1):void{
		if(d == null){
			d = Item.random();
		}
		this.data = d.concat();
		if(dir == -1){
			dir = Math.floor(Math.random() * 4);
		}
		for(let i:number = 0; i < dir; i++){
			this.rotate(false);
		}
		this.draw();
	}

	public getHeight():number{
		return this.data.length;
	}

	public getWidth():number{
		return this.data[0].length;
	}

	public rotate(drawNow:boolean = true):void{
		this.direction +=1;
		if(this.direction > 3){
			this.direction = 0;
		}
		this.data = this.getRotateData();
		if(drawNow){
			this.draw();
		}
	}

	public getRotateData():Array<Array<number>>{
		let w:number = this.getWidth();	
		let h:number = this.getHeight();	
		var newData:Array<Array<number>> = [];
		//Xb=H-Ya; Yb=Xa;
		for(let x:number = 0; x < w; x++){
			for(let y:number = 0; y < h; y++){
				let ny:number = x;
				let nx:number = h - y - 1;
				if(newData[ny] == null){
					newData[ny] = [];
				}
				newData[ny][nx] = this.data[y][x];
			}
		}
		return newData;
	}

	draw():void{
		for(let u of this.unitList){
			u.destroy();
		}
		this.unitList.length = 0;
		let w:number = this.getWidth(); 
		let h:number = this.getHeight();	
		for(let x:number = 0; x < w; x++){
			for(let y:number = 0; y < h; y++){
				let d = this.data[y][x];
				if(d == 0){
					continue;
				}
				let u:Unit = Unit.create(d);
				u.reset(x,y);
				this.addChild(u);
				this.unitList.push(u);
			}
		}
	}

	public merge():void{
		this.unitList.length = 0;
		this.data = null;
		this.gx = 0;
		this.gy = 0;
		this.x = 0;
		this.y = 0;
		if(this.parent != null){
			this.parent.removeChild(this);
		}
		Item.pool.push(this);
	}

	public destroy():void{
		for(let u of this.unitList){
			u.destroy();
		}
		this.merge();
	}
}


